#include <iostream>

#include <unistd.h>
#include <ctime>

#include "pthread.h"
#include "Blockqueue.hpp"
#include "Task.hpp"


using namespace TaskModule;

void *ProducerRoutine(void * arg)
{
    BlockQueueModule::BlockQueue<Task> *bq = static_cast<BlockQueueModule::BlockQueue<Task>*>(arg);

    // int data = 10;
    while(true)
    {
        int x = rand()%10;
        int y = rand()%20;
        Task t(x,y);
        // sleep(2);
        
        bq->Enqueue(t);
        printf("produce a task: %d+%d=?\n", x, y);
        // std::cout << "produce a data: "<< data << std::endl;
    }

}

void *ConsumerRoutine(void * arg)
{
    BlockQueueModule::BlockQueue<Task> *bq = static_cast<BlockQueueModule::BlockQueue<Task>*>(arg);

    // int data = 0;
    while(true)
    {
        Task t;
        sleep(2);
        bq->Dequeue(&t);
        t();
        printf("get a add task %d+%d=%d\n", t.X(),t.Y(),t.Result());
        // std::cout << "get a add task %d+%d=%d " << data << std::endl;

    }
}

int main()
{
    srand(time(nullptr) * getpid());
    BlockQueueModule::BlockQueue<Task> bq;

    pthread_t producer1, consumer1;

    // 多生产者多消费者直接加线程
    // pthread_t p2,p3,p4;
    // pthread_t c1,c2;

    pthread_create(&producer1, nullptr, ProducerRoutine, (void*)&bq);
    pthread_create(&consumer1, nullptr, ConsumerRoutine, (void*)&bq);

    // pthread_create(&p2, nullptr, ProducerRoutine, (void*)&bq);
    // pthread_create(&p3, nullptr, ProducerRoutine, (void*)&bq);
    // pthread_create(&p4, nullptr, ProducerRoutine, (void*)&bq);

    // pthread_create(&c1, nullptr, ConsumerRoutine, (void*)&bq);
    // pthread_create(&c2, nullptr, ConsumerRoutine, (void*)&bq);

    pthread_join(consumer1, nullptr);
    pthread_join(producer1, nullptr);
    // pthread_join(p2, nullptr);
    // pthread_join(p3, nullptr);
    // pthread_join(p4, nullptr);
    // pthread_join(c1, nullptr);
    // pthread_join(c2, nullptr);

    return 0;
}





// void *ProducerRoutine(void * arg)
// {
//     BlockQueueModule::BlockQueue<int> *bq = static_cast<BlockQueueModule::BlockQueue<int>*>(arg);

//     int data = 10;
//     while(true)
//     {
//         // sleep(2);
        
//         bq->Enqueue(data);
//         std::cout << "produce a data: "<< data << std::endl;
//         ++data;
//     }

// }

// void *ConsumerRoutine(void * arg)
// {
//     BlockQueueModule::BlockQueue<int> *bq = static_cast<BlockQueueModule::BlockQueue<int>*>(arg);

//     int data = 0;
//     while(true)
//     {
//         sleep(2);
//         bq->Dequeue(&data);
//         std::cout << "get a data: " << data << std::endl;

//     }
// }